#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import logging
import os
import time

import ujson
from flasgger import Swagger
from flask import Flask, request, Blueprint
from flask_migrate import Migrate
from flask_cors import CORS  # 导入 CORS

from app.models.models import db, init_db_data


from app.routes.api.v1 import (
            VueMgrApi,
            PrjApi,
            WikiApi
        )
from app.routes.api.login_api import LoginApi


# Initialize extensions outside class
instance_path = os.path.join(os.environ['root_path'], 'instance')
app = Flask(__name__, instance_path=instance_path)
migrate = Migrate()
# 允许所有源访问所有路由
CORS(app)

# 可选的 Swagger 配置
swagger_config_path = os.path.join(os.environ['root_path'], 'config', 'swagger_config.json')
with open(swagger_config_path, 'r', encoding='utf-8') as f:
    swagger_config = ujson.loads(f.read())
    app.config['SWAGGER'] = swagger_config
swagger = Swagger(app)


class RestFlaskApp:
    def __init__(self, logger, config):
        self.config = config
        self.logger = logger
        self.logger.debug(f"config: {config}")

        # Initialize Flask app
        with app.app_context():
            self._configure_app()
            self._initialize_extensions()
            self._register_blueprints()
            self._configure_hooks()

    def _configure_app(self):
        """Configure Flask application"""
        db_config = self.config.get('db')
        if db_config['db_type'] == 'sqlite':
            sqlalchemy_database_uri = f'sqlite:///{db_config["db_name"]}'

        app.config.update({
            'SQLALCHEMY_DATABASE_URI': sqlalchemy_database_uri
        })

    def _initialize_extensions(self):
        """Initialize Flask extensions"""
        db.init_app(app)
        migrate.init_app(app, db)

        # Initialize database
        db.create_all()
        init_db_data()

    def _register_blueprints(self):
        """Register all API blueprints"""
        # API Blueprints
        api_blueprints = [
            ('vue_mgr', '/', VueMgrApi),
            ('login', '/dcc/api/login', LoginApi),
            ('prj_info', '/dcc/api/prj_info', PrjApi),
            ('wiki_info', '/dcc/api/wiki_info', WikiApi)
        ]

        for name, url_prefix, api_class in api_blueprints:
            try:
                bp = Blueprint(name, __name__, url_prefix=url_prefix)
                api_class(self.logger, bp)  # Initialize API
                app.register_blueprint(bp)
            except Exception as e:
                self.logger.error(f"init api error, {name}")
                self.logger.exception(str(e))

    def _configure_hooks(self):
        """Configure request hooks"""
        app.before_request(self._before_request)
        app.after_request(self._after_request)

    def _before_request(self):
        """Pre-request processing"""
        request.start_time = time.time()
        if request.path == '/.well-known/appspecific/com.chrome.devtools.json':
            self.logger.debug("ignore path...")
            return '', 204  # 返回空内容+204状态码

    def _after_request(self, response):
        """Post-request processing"""
        elapsed_time = (time.time() - request.start_time) * 1000
        self.logger.debug(
            f"{request.remote_addr} - {request.method} {request.path} "
            f"- Status: {response.status_code} "
            f"- Time: {elapsed_time:.2f}ms"
        )
        return response

    def start(self):
        """Start the Flask application"""
        server_config = self.config.get('server')
        root_path = os.environ['root_path']
        self.logger.debug(f'root path: {root_path}')
        cert_path = f'{root_path}/config/api_ssl/cert.pem'
        key_path = f'{root_path}/config/api_ssl/key.pem'
        app.run(
            host=server_config.get('host', '0.0.0.0'),
            port=int(server_config.get('port', 5001)),
            debug=bool(server_config.get('debug', False)),
            ssl_context=(cert_path, key_path) if int(server_config.get('use_https', 0)) else None
        )
